package p.ithorns.tools.excel.model;

import lombok.Getter;
import lombok.Setter;
import p.ithorns.tools.excel.ValidateContext;
import p.ithorns.tools.excel.Validators;
import p.ithorns.tools.excel.read.ExcelHead;

import javax.validation.MessageInterpolator;
import javax.validation.metadata.ConstraintDescriptor;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * FiledInfo
 * Excel字段信息
 *
 * @author HtL
 * @date 2024/7/11 9:01
 * @since 1.0.0
 */
@ExcelHead(1)
@Getter
@Setter
public final class FieldInfo {

    /**
     * 序号
     */
    private int index;

    /**
     * 字段名
     */
    private String name;

    /**
     * 字段别名 多个
     */
    private String[] aliases;

    /**
     * 头索引
     */
    private int headRow;

    /**
     * 字段引用
     */
    private Field field;

    /**
     * 校验信息
     */
    private Set<ConstraintDescriptor<?>> constraints;


    public FieldInfo() {
    }

    public FieldInfo(int index, String name,
                     String[] aliases,
                     int headRow, Field field) {
        this.index = index;
        this.name = name;
        this.aliases = aliases;
        this.headRow = headRow;
        this.field = field;
    }

    /**
     * 获取主别名
     */
    public String getMainAlias() {
        if (aliases.length == 1) {
            return aliases[0];
        }
        return aliases[headRow];
    }


    /**
     * 获取约束信息
     */
    public String getConstraintMsg() {
        if (null == constraints) {
            return "";
        }

        List<String> msgList = constraints.stream()
                .map(constraint -> {
                    // 获取注解的message模板
                    String messageTemplate = constraint.getMessageTemplate();
                    // 创建Context实现
                    MessageInterpolator.Context context = new ValidateContext(constraint, null);
                    // 使用MessageInterpolator解析消息模板
                    return Validators.interpolate(messageTemplate, context);
                })
                .collect(Collectors.toList());
        return String.join(",", msgList);
    }

    /**
     * 解析消息中的占位符。
     *
     * @param message 消息字符串
     * @return 占位符及其对应的值
     */
    public static Map<String, Object> parsePlaceholders(String message, Annotation annotation) {
        Map<String, Object> placeholders = new HashMap<>();
        Pattern pattern = Pattern.compile("\\{(.+?)\\}");
        Matcher matcher = pattern.matcher(message);

        while (matcher.find()) {
            String placeholder = matcher.group(1);
            placeholders.put(placeholder, getPlaceholderValue(placeholder, annotation));
        }

        return placeholders;
    }

    /**
     * 获取占位符的实际值。
     *
     * @param placeholder 占位符名称
     * @return 实际值
     */
    public static Object getPlaceholderValue(String placeholder, Annotation annotation) {
        Class<? extends Annotation> annotationType = annotation.annotationType();
        Method method = findMethodWithParameterName(annotationType, placeholder);
        if (method != null) {
            try {
                // 调用方法获取实际值
                return method.invoke(annotation);
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
        return null;
    }

    /**
     * 查找具有指定参数名称的方法。
     *
     * @param annotationType 注解类型
     * @param parameterName  参数名称
     * @return 方法对象
     */
    private static Method findMethodWithParameterName(Class<? extends Annotation> annotationType, String parameterName) {
        for (Method method : annotationType.getDeclaredMethods()) {
            if (method.getName().equals(parameterName)) {
                return method;
            }
        }
        return null;
    }
}